package service

import (
	"oa-system/internal/api/request"
	"oa-system/internal/model"
	"oa-system/internal/repository"
	"oa-system/pkg/errors"
)

type RoleService interface {
	GetAllRoles(page, pageSize int, name string) ([]model.Role, int64, error)
	GetRoleByID(id uint) (*model.Role, error)
	CreateRole(req *request.CreateRoleRequest) (*model.Role, error)
	UpdateRole(id uint, req *request.UpdateRoleRequest) (*model.Role, error)
	DeleteRole(id uint) error
	AssignMenusToRole(roleID uint, menuIDs []uint) error
	GetAssignedMenuIDs(roleID uint) ([]uint, error)
}

type roleService struct {
	repo repository.RoleRepository
}

func NewRoleService(repo repository.RoleRepository) RoleService {
	return &roleService{repo: repo}
}

func (s *roleService) GetAllRoles(page, pageSize int, name string) ([]model.Role, int64, error) {
	return s.repo.GetAllRoles(page, pageSize, name)
}

func (s *roleService) GetRoleByID(id uint) (*model.Role, error) {
	return s.repo.GetRoleByID(id)
}

func (s *roleService) CreateRole(req *request.CreateRoleRequest) (*model.Role, error) {
	role := &model.Role{
		Name:        req.Name,
		Description: req.Description,
	}
	return s.repo.CreateRole(role)
}

func (s *roleService) UpdateRole(id uint, req *request.UpdateRoleRequest) (*model.Role, error) {
	role, err := s.repo.GetRoleByID(id)
	if err != nil {
		return nil, errors.NewNotFoundError("角色不存在", err)
	}

	role.Name = req.Name
	role.Description = req.Description

	return s.repo.UpdateRole(role)
}

func (s *roleService) DeleteRole(id uint) error {
	if _, err := s.repo.GetRoleByID(id); err != nil {
		return errors.NewNotFoundError("角色不存在", err)
	}
	return s.repo.DeleteRole(id)
}

func (s *roleService) AssignMenusToRole(roleID uint, menuIDs []uint) error {
	if _, err := s.repo.GetRoleByID(roleID); err != nil {
		return errors.NewNotFoundError("角色不存在", err)
	}
	return s.repo.AssignMenusToRole(roleID, menuIDs)
}

func (s *roleService) GetAssignedMenuIDs(roleID uint) ([]uint, error) {
	if _, err := s.repo.GetRoleByID(roleID); err != nil {
		return nil, errors.NewNotFoundError("角色不存在", err)
	}
	return s.repo.GetAssignedMenuIDs(roleID)
}
